#!/bin/sh /etc/rc.common
# Copyright (C) 2015-2019 iopsys Software Solutions AB

. /lib/functions.sh
include /lib/network
. /usr/share/libubox/jshn.sh

START=99
STOP=10

USE_PROCD=1
PROG="/usr/sbin/icwmpd"
PROG098="/usr/sbin/icwmp_tr098d"

EXTRA_COMMANDS="notify"
EXTRA_HELP="	start	[GetRPCMethods] Start icwmpd service and send GetRPCMethods"

validate_url() {
	# SCHEMA_LIST: contain list of possible schemas that could be present in the acs url
	# Example: SCHEMA_LIST="http https"
	SCHEMA_LIST="http"

	for schema in $SCHEMA_LIST;	do
		dest=`echo $1 | sed 's/$schema:\/\///g' | cut -f1 -d \/ | cut -f1 -d:`
		if [ "_$dest" != "_" ]; then
			return 0
		fi
	done
	return 1
}

build_dmmap_instance() {
	[ ! -e /etc/icwmpd/.icwmpd_backup_session.xml ] && /usr/sbin/icwmp get name "" 0 >/dev/null 2>&1
}

get_acs_url() {
	local default_acs="http://10.10.1.6:8000/openacs/acs"
	local acs_dhcp_discovery="$(uci -q get cwmp.acs.dhcp_discovery)"
	local url="$(uci -q get cwmp.acs.url)"
	local dhcp_url="$(uci -P /var/state -q get cwmp.acs.dhcp_url)"

	if [ "$acs_dhcp_discovery" == "enable" -a -n "$dhcp_url" -o -z "$url" ]; then
		url="$dhcp_url"
		echo "ACS URL from DHCP server: $url"
		[ -n "$url" ] && uci -P /var/state -q set cwmp.acs.url="$url" || url="$default_acs"
	elif [ -n "$url" ];then
		url="$(uci -q get cwmp.acs.url)"
		echo "ACS URL from configuration: $url"
	else
		url="$default_acs"
		echo "Using default ACS URL: $url"
		[ -n "$url" ] && uci -P /var/state -q set cwmp.acs.url="$url"
	fi

	validate_url "$url"
	if [ "$?" != "0" ];then
		echo "Invalid ACS URL: $url"
		exit 1
	fi
}

enable_dhcp_option43() {
	local wan=$1
	local discovery=0
	case $2 in
		enable|1) discovery=1 ;;
	esac

	### Ask for DHCP Option 43 only if CWMP is enabled ###
	local enabled
	local newreqopts=
	local baseopts=
	local reqopts="$(uci -q get network.$wan.reqopts)"
	local proto="$(uci -q get network.$wan.proto)"
	local tropts="43"
	local oldreqopts="$reqopts"
	local ropt iopt
	for ropt in $reqopts; do
		case $ropt in
			43) ;;
			*) baseopts="$baseopts $ropt" ;;
		esac
	done
	ropt=""
	reqopts="$baseopts $tropts"
	for ropt in $reqopts; do
		case $ropt in
			43) [ $discovery -eq 1 ] && newreqopts="$newreqopts $ropt" ;;
			*) newreqopts="$newreqopts $ropt" ;;
		esac
	done
	if [ $proto == "dhcp" ]; then
		newreqopts="$(echo $newreqopts | tr ' ' '\n' | sort -n | tr '\n' ' ' | sed 's/^[ \t]*//;s/[ \t]*$//')"
		oldreqopts="$(echo $oldreqopts | tr ' ' '\n' | sort -n | tr '\n' ' ' | sed 's/^[ \t]*//;s/[ \t]*$//')"
		[ "$newreqopts" == "$oldreqopts" ] && return
		uci -q set network.$wan.reqopts="$newreqopts"
		uci commit network
		ubus call network reload
	fi
	########################################################
}

wait_for_option43() {
	local time=$1
	local default_wan_interface dhcp_discovery url

	config_get default_wan_interface cpe default_wan_interface "wan"
	config_get dhcp_discovery acs dhcp_discovery "0"
	config_get url acs url

	enable_dhcp_option43 $default_wan_interface $dhcp_discovery

	local tm=0

	if [ "$dhcp_discovery" == "enable" -o "$dhcp_discovery" == "1" ]
	then
		echo "Waiting for discovery of ACS URL from dhcp server ..."
		while [ $tm -le $time ]
		do
			acs_url=`uci -P /var/state -q get cwmp.acs.dhcp_url`
			if [ "$acs_url" != "" ]
			then
				break
			else
				sleep 1
			fi
			tm=$((tm+1))
		done
	fi
}

wait_for_wifi() {
	local time=$1
	local tm=1

	while [ ! -f /tmp/wifi.started ]; do
		sleep 1
		[ $tm -ge $time ] && break
		tm=$((tm+1))
	done
}

wait_for_resolvfile() {
	local time=$1
	local tm=1

	local resolvfile="$(uci -q get dhcp.@dnsmasq[0].resolvfile)"
	[ -n "$resolvfile" ] || return

	while [ ! -f $resolvfile ]; do
		sleep 1
		[ $tm -ge $time ] && break
		tm=$((tm+1))
	done
}

wait_for_asterisk() {
	local time=$1
	local tm=1

	while [ -z "$(pidof asterisk)" ]; do
		sleep 1
		[ $tm -ge $time ] && break
		tm=$((tm+1))
	done
}

set_wan_interface() {
	local l3_device=""
	local default_wan_interface=""

	config_get default_wan_interface cpe default_wan_interface "wan"
	json_load "$(ifstatus $default_wan_interface)"
	json_get_var l3_device l3_device
	if [ "$l3_device" != "" ];then
		uci -q set cwmp.cpe.interface="$l3_device"
		uci -q commit cwmp
	fi
}

start_service() {
	if [ ! -f /tmp/.icwmpd_boot ]; then
		touch /etc/icwmpd/.icwmpd_boot
		touch /tmp/.icwmpd_boot
	else
		[ -f /sbin/netifd ] && echo "Waiting for Network to be started ..." && ubus -t 5 wait_for network.interface
		[ -f /etc/config/wireless ] && echo "Waiting for WiFi to be started ..." && wait_for_wifi 20
		[ -f /usr/sbin/dnsmasq ] && echo "Waiting for DNS Proxy to be started ..." && ubus -t 5 wait_for dnsmasq
		[ -f /etc/config/dhcp ] && echo "Waiting for DNS Server(s) ..." && wait_for_resolvfile 20
		[ -f /usr/sbin/asterisk ] && echo "Waiting for Voice to be started ..." && wait_for_asterisk 5

		config_load cwmp
		build_dmmap_instance
		set_wan_interface
		wait_for_option43 20
		get_acs_url

		procd_open_instance
		if [ "$(uci -q get cwmp.cpe.datamodel)" == "tr098" ]; then
			procd_set_param command "$PROG098"
		else
			procd_set_param command "$PROG"
		fi
		if [ "$1" = "GetRPCMethods" ];then
			procd_append_param command -g
		elif [ -f /etc/icwmpd/.icwmpd_boot ]; then
			procd_append_param command -b
		fi
		procd_set_param respawn "3" "7" "0"
		procd_close_instance
	fi
}

reload_service() {
	stop
	start
}

notify() {
       ubus -t 1 call tr069 notify >/dev/null 2>&1 & 
}

service_triggers() {
	procd_add_config_trigger "config.change" "cwmp"  /etc/init.d/icwmpd reload
        if [ "$(uci -q get cwmp.cpe.notification)" == "1" ]; then
		for conf in $(ls /etc/config/); do
			[ "$conf" == "cwmp" ] && continue
			procd_add_config_trigger "config.change" "$conf" /etc/init.d/icwmpd notify
		done
	fi
}

